package com.skyworth.demo.startactivity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebView;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MainActivity extends Activity {
    private static abstract class Item extends LinearLayout {
        protected static final String CODE_HEAD = "Intent intent = new Intent();\n";
        protected static final String CODE_SET_PACKAGE = "intent.setPackage(%s);\n";
        protected static final String CODE_SET_CLASS = "intent.setClassName(%s, %s);\n";
        protected static final String CODE_SET_EXTRAS = "intent.putExtra(%s, %s);\n";
        protected static final String CODE_SET_URI = "intent.setData(Uri.parse(%s));\n";
        protected static final String CODE_SET_ACTION = "intent.setAction(%s);\n";
        protected static final String CODE_END = "context.startActivity(intent);";

        private TextView intentCode = null;
        private EditText editor = null;

        public Item(final Context context, String title) {
            super(context);
            setOrientation(VERTICAL);

            TextView textView = new TextView(context);
            textView.setText(title);
            addView(textView);

            editor = new EditText(context);
            editor.addTextChangedListener(new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(final Editable s) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                final StringBuffer sb = new StringBuffer(CODE_HEAD);
                                sb.append(getIntentCode());
                                if (enableParams()) {
                                    Map<String, String> params = getParams();
                                    if (params != null) {
                                        Set<String> keys = params.keySet();
                                        for (String key : keys)
                                            sb.append(String.format(CODE_SET_EXTRAS, key, params.get(key)));
                                    }
                                }
                                sb.append(CODE_END);
                                uiHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        if (s.length() > 0)
                                            intentCode.setText(sb.toString());
                                        else
                                            intentCode.setText(getTips());
                                    }
                                });
                            } catch (Exception e) {
                                e.printStackTrace();
                                uiHandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        intentCode.setText(getTips());
                                    }
                                });
                            }
                        }
                    });
                }
            });
            editor.setOnKeyListener(new OnKeyListener() {
                @Override
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    if (event.getAction() == KeyEvent.ACTION_UP)
                        return true;
                    switch (keyCode) {
                        case KeyEvent.KEYCODE_ENTER: {
                            if (event.isCtrlPressed()) {
                                try {
                                    Intent intent = getIntent();
                                    if (enableParams()) {
                                        Map<String, String> params = getParams();
                                        if (params != null) {
                                            Set<String> keys = params.keySet();
                                            for (String key : keys)
                                                intent.putExtra(key, params.get(key));
                                        }
                                    }
                                    context.startActivity(intent);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                    Toast.makeText(context, e.getMessage(), Toast.LENGTH_LONG).show();
                                }
                                return true;
                            }
                        }
                        case KeyEvent.KEYCODE_D: {
                            if (event.isCtrlPressed()) {
                                editor.setText("");
                                intentCode.setText(getTips());
                                return true;
                            }
                        }
                        break;
                    }
                    return false;
                }
            });
            addView(editor);


            intentCode = new TextView(context);
            intentCode.setText(getTips());
            addView(intentCode);
        }

        public abstract String getIntentCode() throws Exception;

        public abstract Intent getIntent() throws Exception;

        public abstract String getTips();

        protected boolean enableParams() {
            return true;
        }

        protected final String getEditorText() {
            return editor.getText().toString();
        }

        protected Map<String, String> getParams() {
            try {
                String text = getEditorText();
                BufferedReader br = new BufferedReader(new StringReader(text));
                br.readLine();//skip packagName and ***
                Map<String, String> map = null;
                while ((text = br.readLine()) != null) {
                    String[] kvs = text.split("=");
                    if (kvs != null && kvs.length == 2) {
                        if (map == null)
                            map = new HashMap<String, String>();
                        map.put(kvs[0], kvs[1]);
                    }
                }
                return map;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    private static class ByActivity extends Item {
        private static final String TIPS = "按此格式输入内容：\n包名|类名\nkey=value\nkey=value\n(注:ctrl+D删除所有，ctrl+回车执行)";

        public ByActivity(Context context) {
            super(context, "ByActivity");
        }

        @Override
        public String getIntentCode() throws Exception {
            StringBuffer sb = new StringBuffer(String.format(CODE_SET_CLASS, getPackageName(), getClassName()));
            return sb.toString();
        }

        @Override
        public Intent getIntent() throws Exception {
            Intent intent = new Intent();
            intent.setClassName(getPackageName(), getClassName());
            return intent;
        }

        @Override
        public String getTips() {
            return TIPS;
        }

        private String getPackageName() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2)
                    return values[0];
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getPackageName null");
        }

        private String getClassName() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2)
                    return values[1];
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getClassName null");
        }
    }

    private static class ByURI extends Item {
        private static final String TIPS = "按此格式输入内容：\n包名|URI\nkey=value\nkey=value\n(注:ctrl+D删除所有，ctrl+回车执行)";

        public ByURI(Context context) {
            super(context, "ByURI");
        }

        @Override
        public String getIntentCode() throws Exception {
            StringBuffer sb = new StringBuffer(String.format(CODE_SET_PACKAGE, getPackageName()));
            sb.append(String.format(CODE_SET_URI, getURI()));
            return sb.toString();
        }

        @Override
        public Intent getIntent() throws Exception {
            Intent intent = new Intent();
            intent.setPackage(getPackageName());
            intent.setData(getURI());
            return intent;
        }

        @Override
        public String getTips() {
            return TIPS;
        }

        private String getPackageName() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2)
                    return values[0];
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getPackageName null");
        }


        protected boolean enableParams() {
            return false;
        }
        private Uri getURI() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2) {
                    String u = values[1];
                    Uri _uri = Uri.parse(u);
                    Uri.Builder builder = _uri.buildUpon();
                    Map<String, String> p = getParams();
                    if (p != null) {
                        Set<String> keys = p.keySet();
                        for (String key : keys)
                            builder = builder.appendQueryParameter(key, p.get(key));
                    }
                    return builder.build();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getURI null");
        }
    }

    private static class ByAction extends Item {
        private static final String TIPS = "按此格式输入内容：\n包名|Action\nkey=value\nkey=value\n(注:ctrl+D删除所有，ctrl+回车执行)";

        public ByAction(Context context) {
            super(context, "ByAction");
        }

        @Override
        public String getIntentCode() throws Exception {
            StringBuffer sb = new StringBuffer(String.format(CODE_SET_PACKAGE, getPackageName()));
            sb.append(String.format(CODE_SET_ACTION, getAction()));
            return sb.toString();
        }

        @Override
        public Intent getIntent() throws Exception {
            Intent intent = new Intent();
            intent.setPackage(getPackageName());
            intent.setData(Uri.parse(getAction()));
            return intent;
        }

        @Override
        public String getTips() {
            return TIPS;
        }

        private String getPackageName() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2)
                    return values[0];
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getPackageName null");
        }

        private String getAction() throws Exception {
            String text = getEditorText();
            BufferedReader br = new BufferedReader(new StringReader(text));
            try {
                text = br.readLine();
                String[] values = text.split("\\|");
                if (values != null && values.length == 2)
                    return values[1];
            } catch (Exception e) {
                e.printStackTrace();
            }
            throw new Exception("getAction null");
        }

    }

    private static HandlerThread ht = null;
    private static Handler handler = null;
    private static Handler uiHandler = new Handler(Looper.getMainLooper());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


        LinearLayout root = new LinearLayout(this);
        root.setOrientation(LinearLayout.HORIZONTAL);

        LinearLayout itemLayout = new LinearLayout(this);
        itemLayout.setOrientation(LinearLayout.VERTICAL);
        root.addView(itemLayout);


        WebView webView = new WebView(this);
        root.addView(webView);


        itemLayout.addView(new ByActivity(this));
        itemLayout.addView(new ByAction(this));
        itemLayout.addView(new ByURI(this));


        setContentView(root);
        if (ht == null) {
            ht = new HandlerThread("");
            ht.start();
            handler = new Handler(ht.getLooper());
        }
    }
}
